package cn.iocoder.yudao.module.fengdong.smartelderly.service.oldman;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
import cn.iocoder.yudao.module.fengdong.smartelderly.utils.QrCodeUtils;
import cn.iocoder.yudao.module.fengdong.smartelderly.utils.vo.ActivityRecordBaseVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
import cn.iocoder.yudao.module.system.convert.user.UserConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

import cn.iocoder.yudao.module.fengdong.smartelderly.controller.admin.oldman.vo.*;
import cn.iocoder.yudao.module.fengdong.smartelderly.dal.dataobject.oldman.OldmanDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.fengdong.smartelderly.convert.oldman.OldmanConvert;
import cn.iocoder.yudao.module.fengdong.smartelderly.dal.mysql.oldman.OldmanMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder.getTenantId;
import static cn.iocoder.yudao.module.fengdong.smartelderly.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.fengdong.smartelderly.utils.IdentityCardUtils.verifyIdentityCard;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.TREATMENT_USER_NOT_EXISTS_IDENTITYCARD;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;

/**
 * 老人管理 Service 实现类
 *
 * @author 沣东养老院管理员
 */
@Service
@Validated
public class OldmanServiceImpl implements OldmanService {

    @Resource
    private OldmanMapper oldmanMapper;

    @Autowired
    QrCodeUtils qrCodeUtils;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOldman(OldmanCreateReqVO createReqVO) throws IOException {
        //身份证校验
        if (StringUtil.isNotBlank(createReqVO.getIdentityCard()) || StringUtil.isNotBlank(createReqVO.getGuardianCard())){
            verifyIdentityCard(createReqVO.getIdentityCard());
            verifyIdentityCard(createReqVO.getGuardianCard());
        }
        //手机号校验
        if (StringUtil.isNotBlank(createReqVO.getPhoneNumber()) || StringUtil.isNotBlank(createReqVO.getGuardianNumber())) {
            isValidContactInformation(createReqVO.getPhoneNumber());
            isValidContactInformation(createReqVO.getGuardianNumber());
        }

        // 插入
        OldmanDO oldman = OldmanConvert.INSTANCE.convert(createReqVO);
        //判断该手机号或该手机号被登记
        if(ObjectUtil.isNotEmpty(oldmanMapper.selectCountByCardANDPhone(oldman))) {
            throw exception(OLDMAN_PHONE_CARD_EXISTS);
        }

        ActivityRecordBaseVO recordBaseVO = new ActivityRecordBaseVO().setActivityKind(3L)
                .setUserType(4L).setUserId(oldman.getId())
                .setTenantId(getTenantId());
        recordBaseVO.setTenantId(getTenantId());
        String qrCode = qrCodeUtils.getQrCode(recordBaseVO);
        oldman.setQrUrl(qrCode);

        oldmanMapper.insert(oldman);
        // 返回
        return oldman.getId();
    }

    /**
     * 联系方式校验  只允许手机号
     * @param contactInformation
     */
    public static void isValidContactInformation(String contactInformation) {
        // 手机号正则表达式
        String phoneRegex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\d{8}$";
        boolean ruslt = Pattern.matches(phoneRegex, contactInformation);
        if (!ruslt) {
            throw exception(PHONE_CONTACT_INFORMATION);
        }
    }
    @Override
    public void updateOldman(OldmanUpdateReqVO updateReqVO) throws IOException {
        // 校验存在
        validateOldmanExists(updateReqVO.getId());
        //身份证校验
        if (StringUtil.isNotBlank(updateReqVO.getIdentityCard())){
            verifyIdentityCard(updateReqVO.getIdentityCard());
        }
        //手机号校验
        if (StringUtil.isNotBlank(updateReqVO.getPhoneNumber())) {
            isValidContactInformation(updateReqVO.getPhoneNumber());
        }

        // 更新
        OldmanDO updateObj = OldmanConvert.INSTANCE.convert(updateReqVO);

        //判断该手机号或该手机号被登记
        if(StringUtil.isNotBlank(updateReqVO.getIdentityCard()) || StringUtil.isNotBlank(updateReqVO.getPhoneNumber())) {
            if (oldmanMapper.selectCountByCardANDPhone(updateObj).getId() != updateObj.getId()){
                throw exception(OLDMAN_PHONE_CARD_EXISTS);
            }
        }

//        ActivityRecordBaseVO recordBaseVO = new ActivityRecordBaseVO().setActivityKind(3L)
//                .setUserType(4L).setUserId(updateObj.getId())
//                .setTenantId(getTenantId());
//        String qrCode = QrCodeUtils.getQrCode(recordBaseVO);
//        updateObj.setQrUrl(qrCode);

        oldmanMapper.updateById(updateObj);
    }

    @Override
    public void deleteOldman(Long id) {
        // 校验存在
        validateOldmanExists(id);
        // 删除
        oldmanMapper.deleteById(id);
    }

    private void validateOldmanExists(Long id) {
        if (oldmanMapper.selectById(id) == null) {
            throw exception(OLDMAN_NOT_EXISTS);
        }
    }

    @Override
    public OldmanDO getOldman(Long id) {
        return oldmanMapper.selectById(id);
    }

    @Override
    public List<OldmanDO> getOldmanList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return oldmanMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OldmanDO> getOldmanPage(OldmanPageReqVO pageReqVO) {
        return oldmanMapper.selectPage(pageReqVO);
    }

    @Override
    public List<OldmanDO> getOldmanList(OldmanExportReqVO exportReqVO) {
        return oldmanMapper.selectList(exportReqVO);
    }

    @Override
    public List<OldmanDO> getUserList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return oldmanMapper.selectBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务，异常则回滚所有导入
    public OldManIImportRespVO importOldmanList(List<OldmanImportExcelVO> importOldmans, Boolean isUpdateSupport) {

        if (CollUtil.isEmpty(importOldmans)) {
            throw exception(OLDMAN_IMPORT_LIST_IS_EMPTY);
        }
        OldManIImportRespVO respVO = OldManIImportRespVO.builder().createOldMannames(new ArrayList<>())
                .updateOldMannames(new ArrayList<>()).failureOldMannames(new LinkedHashMap<>()).build();
        importOldmans.forEach(importUser -> {
            // 校验，判断是否有不符合的原因
            try {
                validateOldMancard(importUser);
            } catch (ServiceException ex) {
                respVO.getFailureOldMannames().put(importUser.getName(), ex.getMessage());
                return;
            }
            // 判断如果不存在，在进行插入
            OldmanDO oldmanDO = oldmanMapper.selectOldManByIdentityCard(importUser);
            if (oldmanDO == null) {
                oldmanMapper.insert(OldmanConvert.INSTANCE.convert(importUser)); //
                respVO.getCreateOldMannames().add(importUser.getName());
                return;
            }
            // 如果存在，判断是否允许更新
            if (!isUpdateSupport) {
                respVO.getFailureOldMannames().put(importUser.getName(), USER_USERNAME_EXISTS.getMsg());
                return;
            }
            OldmanDO updateUser = OldmanConvert.INSTANCE.convert(importUser);
            updateUser.setId(oldmanDO.getId());
            oldmanMapper.updateById(updateUser);
            respVO.getUpdateOldMannames().add(importUser.getName());
        });
        return respVO;
    }

    private void validateOldMancard(OldmanImportExcelVO oldmanImportExcelVO) {
        // 关闭数据权限，避免因为没有数据权限，查询不到数据，进而导致唯一校验不正确
            // 校验老人身份证/手机号 是否已经添加
        if (StringUtil.isBlank(oldmanImportExcelVO.getIdentityCard()) || !IdcardUtil.isValidCard(oldmanImportExcelVO.getIdentityCard())){
            throw exception(TREATMENT_USER_NOT_EXISTS_IDENTITYCARD);
        }

        if (StringUtil.isNotBlank(oldmanImportExcelVO.getPhoneNumber()) ){
            isValidContactInformation(oldmanImportExcelVO.getPhoneNumber());
        }
    }


}
